/*
 * ParamSet.cpp
 *
 *  Created on: 2015年12月20日
 *      Author: terry
 */

#include "ParamSet.h"
#include <algorithm>
#include "TStringUtil.h"


namespace util
{

ParamSet::ParamSet()
{
}

ParamSet::~ParamSet()
{
}

void ParamSet::set(const char* key, const char* value)
{
	comn::AutoCritSec lock(m_cs);
	m_map[key] = value;
}

void ParamSet::set(const std::string& key, const std::string& value)
{
	comn::AutoCritSec lock(m_cs);
	m_map[key] = value;
}

std::string ParamSet::toString()
{
	return toString(SEPERATOR, SEG);
}

std::string ParamSet::toString(char sep, char seg)
{
	comn::AutoCritSec lock(m_cs);

	std::ostringstream ss;
	size_t count = 0;
	StringMap::const_iterator it = m_map.begin();
	for (; it != m_map.end(); ++ it)
	{
		if (count != 0)
		{
			ss << seg;
		}

		ss << it->first << sep << it->second;

		count ++;
	}
	return ss.str();
}

bool ParamSet::fromString(const std::string& str, char sep, char seg)
{
	comn::AutoCritSec lock(m_cs);

	m_map.clear();
	return parse(str, sep, seg);
}

bool ParamSet::parse(const std::string& str, char sep, char seg)
{
	comn::AutoCritSec lock(m_cs);

	std::string key;
	std::string value;
	size_t fromIdx = 0;
	for (size_t i = 0; i < str.size(); ++ i)
	{
		if (str[i] == sep)
		{
			key = str.substr(fromIdx, i - fromIdx);
			fromIdx = i + 1;
		}
		else if (str[i] == seg)
		{
			value = str.substr(fromIdx, i - fromIdx);
			fromIdx = i + 1;

			if (!key.empty())
			{
				m_map[key] = value;
			}

			key.clear();
			value.clear();
		}
		else
		{
			// pass
		}
	}

	if (!key.empty())
	{
		value = str.substr(fromIdx);
		m_map[key] = value;
	}

	return true;
}

bool ParamSet::get(const std::string& key, std::string& value)
{
	comn::AutoCritSec lock(m_cs);

	bool found = false;
	StringMap::const_iterator it = m_map.find(key);
	if (it != m_map.end())
	{
		value = it->second;
		found = true;
	}
	return found;
}

size_t ParamSet::size()
{
	comn::AutoCritSec lock(m_cs);

	return m_map.size();
}

bool ParamSet::getAt(size_t idx, std::string& key, std::string& value)
{
	comn::AutoCritSec lock(m_cs);

	if (idx >= m_map.size())
	{
		return false;
	}

	bool found = false;
	StringMap::const_iterator it = m_map.begin();
	std::advance(it, idx);
	if (it != m_map.end())
	{
		key = it->first;
		value = it->second;
		found = true;
	}
	return found;
}

void ParamSet::clear()
{
	comn::AutoCritSec lock(m_cs);

	m_map.clear();
}

bool ParamSet::exists(const std::string& key)
{
	comn::AutoCritSec lock(m_cs);
	StringMap::const_iterator it = m_map.find(key);
	return (it != m_map.end());
}

size_t ParamSet::filter(const std::string& sec, ParamSet& dest)
{
	comn::AutoCritSec lock(m_cs);
	size_t count = 0;

	StringMap::const_iterator it = m_map.begin();
	for (; it != m_map.end(); ++ it)
	{
		if (comn::StringUtil::startsWith(it->first, sec))
		{
			std::string head;
			std::string tail;
			comn::StringUtil::split(it->first, SPLITTER, head, tail);
			dest.set(tail, it->second);
			count ++;
		}
	}

	return count;
}


} /* namespace av */
